home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / waisgate / transprt.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  12KB  |  472 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4. */
  5.  
  6. #ifndef lint
  7. static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/ir/RCS/transprt.c,v 1.2 92/02/12 13:51:34 jonathan Exp $";
  8. #endif
  9.  
  10. /* this is a krufty transport layer for comm mediums that can not handle
  11.  * all 8 bits of ascii.
  12.  * Written by Harry Morris, modified by brewster.
  13.  * Hexcode written by Steve Swartz
  14.  * 
  15.  */
  16.  
  17. /* to do
  18.  *
  19.  *  compression
  20.  *  encryption
  21.  */
  22.  
  23. /* Change log:
  24.  * $Log:    transprt.c,v $
  25.  * Revision 1.2  92/02/12  13:51:34  jonathan
  26.  * Added "$Log" so RCS will put the log message in the header
  27.  * 
  28.  * 
  29.  * 7/7/90 -brewster
  30.  * merged arts and harry's changes 7/7/90 -brewster
  31.  *
  32.  * 11/6/90 -tracy
  33.  * shift 6 bytes starting from [ as IBM gateway program
  34.  * masks out characters [\]^` in input,
  35.  * append H and I to the function names corresponding to the
  36.  * oroginal coding and the modified one. 'I' indicates IBM. 
  37.  */
  38.  
  39. #include "transprt.h"
  40. #include "wmessage.h" 
  41. #include "ustubs.h"
  42.  
  43. /*---------------------------------------------------------------------*/
  44. static char alphaH[] = /* Must be 65 consecutive ascii characters */
  45.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop";
  46.  
  47.  
  48. /*---------------------------------------------------------------------*/
  49.  
  50. static void hexCodeH _AP((char* data,long* len));
  51.  
  52. static void
  53. hexCodeH(data,len)
  54. char* data;
  55. long* len;
  56. /* compose a message for sending over ascii terminal lines. Input is '*len'
  57.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  58.  *
  59.  * Encoding goes like this. Let capital letters represent bits:
  60.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  61.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  62.  *
  63.  * 1 byte at end: ABCDEFGH
  64.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  65.  *
  66.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  67.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  68.  */
  69. {
  70.   long i, j;
  71.   
  72.   switch (*len % 3)
  73.     {
  74.     case 2:
  75.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  76.       data[j]   = alphaH[64];
  77.       data[j-1] = alphaH[data[i-1] & 0x0f];
  78.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  79.       data[j-3] = alphaH[data[i-2] & 0x3F];
  80.       break;
  81.     case 1:
  82.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  83.       data[j]   = alphaH[64];
  84.       data[j-1] = alphaH[64];
  85.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2];
  86.       data[j-3] = alphaH[data[i-2] & 0x3F];
  87.       break;
  88.     default:
  89.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  90.       break;
  91.     }
  92.   
  93.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  94.     { 
  95.       data[j]   = alphaH[data[i] & 0x3F];
  96.       data[j-1] = alphaH[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  97.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  98.       data[j-3] = alphaH[data[i-2] & 0x3F];
  99.     }
  100. }
  101.  
  102. /*---------------------------------------------------------------------*/
  103.  
  104. static void hexDecodeH _AP((char* data,long* len));
  105.  
  106. static void
  107. hexDecodeH(data,len)
  108. char* data;
  109. long* len;
  110. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  111.  *  will always be divisble by 4. Output is the binary bytes that were 
  112.  *  encoded into 'data'.
  113.  *
  114.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  115.  *  from ascii data to the 'bX' values has to become more complicated than
  116.  *  data[] - alpha[0].
  117.  */
  118. {
  119.   unsigned char b0, b1, b2, b3;
  120.   long i, j;
  121.  
  122.   
  123.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  124.     {
  125.       b0 = (data[j-4] & 0x07F) - alphaH[0];
  126.       b1 = (data[j-3] & 0x07F) - alphaH[0];
  127.       b2 = (data[j-2] & 0x07F) - alphaH[0];
  128.       b3 = (data[j-1] & 0x07F) - alphaH[0];
  129.       data[i-3] = b0 | (b1 & 0x30) << 2;
  130.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  131.       data[i-1] = b3 | (b2 & 0x30) << 2;
  132.     }
  133.  
  134.   *len = *len/4 * 3 - 2;
  135.   b0 = (data[j-4] & 0x07F) - alphaH[0];
  136.   b1 = (data[j-3] & 0x07F) - alphaH[0];
  137.   b2 = (data[j-2] & 0x07F) - alphaH[0];
  138.   b3 = (data[j-1] & 0x07F) - alphaH[0];
  139.   data[i-3] = b0 | (b1 & 0x30) << 2;
  140.  
  141.   if (b2 != 64)    
  142.     {
  143.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  144.       (*len)++;
  145.     }
  146.  
  147.   if (b3 != 64)
  148.     {
  149.       data[i-1] = b3 | (b2 & 0x30) << 2;
  150.       (*len)++;
  151.     }
  152. }
  153.  
  154. /*---------------------------------------------------------------------*/
  155.  
  156. void
  157. transportCodeH(data,len)
  158. char* data;
  159. long* len;
  160. /* krufty serial line transport layer - encode in hex and append in cr */
  161. /* Now it also writes a wais packet header on to the front of the packet.
  162.  *   --art 
  163.  */
  164.   hexCodeH(data,len);
  165.   data[*len] = '\r';
  166.   data[*len + 1] = '\0';
  167.   *len += 1;
  168. }
  169.  
  170. /*---------------------------------------------------------------------*/
  171.  
  172. void
  173. transportDecodeH(data,len)
  174. char* data;
  175. long* len;
  176. /* decode above */
  177. /* This does not have to deal with the wais packet header since it has
  178.    been removed at the end of the read.  */
  179.   if (*len == 0)
  180.     return;
  181.     
  182.   *len -= 1;
  183.   hexDecodeH(data,len);
  184. }
  185.  
  186. /*---------------------------------------------------------------------
  187.  Below are the set of transport coding/decoding functions for clients
  188.  dialing through IBM to DowQuest. Unlike the above one that
  189.  uses 65 consecutive ASCII character for the coding/decoding table,
  190.  table entries after charcater 'Z' are shift 6 characters.
  191.  *--------------------------------------------------------------------*/ 
  192.  
  193. #define LAST_NON_SHIFT_CHAR 90
  194. #define SHIFT_OFFSET   6
  195.  
  196. static char alphaI[] = 
  197.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
  198.  
  199.  
  200. static void hexCodeI _AP((char* data,long* len));
  201.  
  202. static void
  203. hexCodeI(data,len)
  204. char* data;
  205. long* len;
  206. /* compose a message for sending over ascii terminal lines. Input is '*len'
  207.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  208.  *
  209.  * Encoding goes like this. Let capital letters represent bits:
  210.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  211.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  212.  *
  213.  * 1 byte at end: ABCDEFGH
  214.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  215.  *
  216.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  217.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  218.  */
  219. {
  220.   long i, j;
  221.   
  222.   switch (*len % 3)
  223.     {
  224.     case 2:
  225.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  226.       data[j]   = alphaI[64];
  227.       data[j-1] = alphaI[data[i-1] & 0x0f];
  228.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  229.       data[j-3] = alphaI[data[i-2] & 0x3F];
  230.       break;
  231.     case 1:
  232.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  233.       data[j]   = alphaI[64];
  234.       data[j-1] = alphaI[64];
  235.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2];
  236.       data[j-3] = alphaI[data[i-2] & 0x3F];
  237.       break;
  238.     default:
  239.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  240.       break;
  241.     }
  242.   
  243.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  244.     { 
  245.       data[j]   = alphaI[data[i] & 0x3F];
  246.       data[j-1] = alphaI[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  247.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  248.       data[j-3] = alphaI[data[i-2] & 0x3F];
  249.     }
  250. }
  251.  
  252. /*---------------------------------------------------------------------*/
  253.  
  254. static void hexDecodeI _AP((char* data,long * len));
  255.  
  256. static void
  257. hexDecodeI(data,len)
  258. char* data;
  259. long* len;
  260. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  261.  *  will always be divisble by 4. Output is the binary bytes that were 
  262.  *  encoded into 'data'.
  263.  *
  264.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  265.  *  from ascii data to the 'bX' values has to become more complicated than
  266.  *  data[] - alpha[0].
  267.  */
  268. {
  269.   unsigned char b0, b1, b2, b3;
  270.   long i, j;
  271.  
  272.   for ( i=0; i < *len ; i++ )
  273.     if ( data[i] > LAST_NON_SHIFT_CHAR ) data[i] -= SHIFT_OFFSET;
  274.   
  275.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  276.     {
  277.       b0 = (data[j-4] & 0x07F) - alphaI[0];
  278.       b1 = (data[j-3] & 0x07F) - alphaI[0];
  279.       b2 = (data[j-2] & 0x07F) - alphaI[0];
  280.       b3 = (data[j-1] & 0x07F) - alphaI[0];
  281.       data[i-3] = b0 | (b1 & 0x30) << 2;
  282.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  283.       data[i-1] = b3 | (b2 & 0x30) << 2;
  284.     }
  285.  
  286.   *len = *len/4 * 3 - 2;
  287.   b0 = (data[j-4] & 0x07F) - alphaI[0];
  288.   b1 = (data[j-3] & 0x07F) - alphaI[0];
  289.   b2 = (data[j-2] & 0x07F) - alphaI[0];
  290.   b3 = (data[j-1] & 0x07F) - alphaI[0];
  291.   data[i-3] = b0 | (b1 & 0x30) << 2;
  292.  
  293.   if (b2 != 64)    
  294.     {
  295.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  296.       (*len)++;
  297.     }
  298.  
  299.   if (b3 != 64)
  300.     {
  301.       data[i-1] = b3 | (b2 & 0x30) << 2;
  302.       (*len)++;
  303.     }
  304. }
  305.  
  306. /*---------------------------------------------------------------------*/
  307.  
  308. void
  309. transportCodeI(data,len)
  310. char* data;
  311. long* len;
  312. /* krufty serial line transport layer - encode in hex and append in cr */
  313. /* Now it also writes a wais packet header on to the front of the packet.
  314.  *   --art 
  315.  */
  316.   hexCodeI(data,len);
  317.   data[*len] = '\r';
  318.   data[*len + 1] = '\0';
  319.   *len += 1;
  320. }
  321.  
  322. /*---------------------------------------------------------------------*/
  323.  
  324. void
  325. transportDecodeI(data,len)
  326. char* data;
  327. long* len;
  328. /* decode above */
  329. /* This does not have to deal with the wais packet header since it has
  330.    been removed at the end of the read.  */
  331.   if (*len == 0)
  332.     return;
  333.     
  334.   *len -= 1;
  335.   hexDecodeI(data,len);
  336. }
  337.  
  338. /*---------------------------------------------------------------------*/
  339.  
  340.  
  341. #ifdef NOTDEFINED /* here for back compatibility */
  342.  
  343. static void hexCode _AP((char* data,long * len));
  344.  
  345. static void
  346. hexCode(data,len)
  347. char* data;
  348. long* len;
  349. /* compose a message for sending over ascii terminal lines.  The data is hex,
  350.  */
  351. { long i;
  352.   for (i = *len-1; i >= 0; i--)
  353.     { data[i*2+1] = (data[i]&0x0F) + 'a';
  354.       data[i*2] = ((data[i]>>4)&0x0F) + 'a';
  355.     }
  356.   data[*len*2] = '\0';
  357.   *len = *len * 2;
  358. }
  359.  
  360. /*---------------------------------------------------------------------------*/
  361.  
  362. static void hexDecode _AP((char* data,long * len));
  363.  
  364. static void
  365. hexDecode(data,len)
  366. char* data;
  367. long* len;
  368. /* converts a buffer full of dataLen bytes of hex in place into the
  369. equivalent binary form. len is filled with the actual number of binary bytes.
  370.  */
  371. { long i;
  372.   *len = *len / 2;
  373.   for (i = 0; i < *len; i++)
  374.     { long temp = 0;
  375.       temp = (data[i*2]-'a')<<4;
  376.       temp += data[i*2+1]-'a';
  377.       data[i] = (char)temp;
  378.     }
  379.   data[*len] = '\0';
  380. }
  381.  
  382. #endif /* def NOTDEFINED */
  383. /*---------------------------------------------------------------------------*/
  384.  
  385. boolean
  386. transportCode(encoding,data,len)
  387. long encoding;
  388. char* data;
  389. long* len;
  390. /* krufty serial line transport layer - encode in hex and add trailing nl */
  391. {
  392.   switch (encoding){
  393.   case NO_ENCODING:
  394.     /* do nothing */
  395.     return(true);
  396.   case HEX_ENCODING:
  397.     transportCodeH(data,len);
  398.     return(true);
  399.   case IBM_HEXCODING:
  400.     transportCodeI(data,len);
  401.     return(true);
  402.   default:
  403.     return(false);
  404.   }
  405. }
  406.  
  407. /*---------------------------------------------------------------------------*/
  408.  
  409. boolean
  410. transportDecode(encoding,data,len)
  411. long encoding;
  412. char* data;
  413. long* len;
  414. /* decode above */
  415. {
  416.   switch (encoding){
  417.   case NO_ENCODING:
  418.     /* do nothing */
  419.     return(true);
  420.   case HEX_ENCODING:
  421.     transportDecodeH(data,len);
  422.     return(true);
  423.   case IBM_HEXCODING:
  424.     transportDecodeI(data,len);
  425.     return(true);
  426.   default:
  427.     return(false);
  428.   }
  429. }
  430.  
  431. /*---------------------------------------------------------------------------*/
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438. #ifdef old /* from the bad old days */
  439.  
  440.  
  441. /*---------------------------------------------------------------------------*/
  442.  
  443. void
  444. transportCode(data,len)
  445. char* data;
  446. long* len;
  447. /* krufty serial line transport layer - encode in hex and add trailing nl */
  448. {
  449.   hexCode(data,len);
  450.   data[*len] = '\r';
  451.   data[*len+1] = '\0';
  452. }
  453.  
  454. /*---------------------------------------------------------------------------*/
  455.  
  456. void
  457. transportDecode(data,len)
  458. char* data;
  459. long* len;
  460. /* decode above */
  461. {
  462.   hexDecode(data,len);
  463. }
  464.  
  465. /*---------------------------------------------------------------------------*/
  466.  
  467. #endif /* old */
  468.